window.GlobalConstants = {
	// Treasure target height , assume the treasure is a square
	TREASURE_MAX_WIDTH : 105,
	// used to trigger a animation.
	ANIMATION_TRIGGER_ID : "animationTrigger",
	//
	CLONED_TREASURE_ID_SUFFIX : "-animation",
	//
	ANIMATIOIN_MASKER_ID : "animation-masker"
};
/**
 * Define the Position class to store the X,Y value
 */
var Position = function(x, y) {
	this.x = x;
	this.y = y;
};

/**
 * Define a animation utility Class.
 */
var AnimationUtil = {
	initEnvironment : function() {
		var id = "#" + GlobalConstants.ANIMATION_TRIGGER_ID;
		var trigger = $(id);
		if (trigger == null || trigger == 'undefined' || trigger.length == 0) {
			$("<div/>").attr("id", GlobalConstants.ANIMATION_TRIGGER_ID).css({
				"width" : "0px",
				"height" : "0px",
				"visibility" : "hidden"
			}).appendTo($("body"));
		}
	},

	createPageMasker : function(e) {
		var w = $(window).width(), h = $(window).height();
		var marker = $("<div/>");

		marker.attr("id", GlobalConstants.ANIMATIOIN_MASKER_ID).css({
			"position" : "absolute",
			"top" : "0px",
			"left" : "0px",
			"z-index" : "100",
			"width" : w + "px",
			"height" : h + "px"
		}).appendTo($("body"));
		return marker;
	},

	removeMasker : function(e) {
		$("#" + Constants.ANIMATIOIN_MASKER_ID).remove();
	},

	removePageMasker : function(e) {
		$("#animation-masker").remove();
	},

	/**
	 * Get the absolute x,y coordinate consider the page scroll.
	 */
	getAbsoluteCenterPosition : function(e) {
		var lattice = AnimationUtil.getLattice(e);
		var x = ($(document).width() - lattice.width()) / 2;
		var y = $('html').scrollTop() + ($(window).height() - lattice.height()) / 2;
		return new Position(x, y);
	},
	/**
	 * Clone a new treasure for animation display. The original treasure keep in
	 * the place staticly.
	 */
	cloneAnimationTreasure : function(e) {
		var lattice = AnimationUtil.getLattice(e);
		var treasure = AnimationUtil.getTreasure(e);
		var clone = treasure.clone();

		var x = lattice.offset().left + "px", y = lattice.offset().top + "px";
		clone.attr("id", treasure.attr("id") + GlobalConstants.CLONED_TREASURE_ID_SUFFIX).removeAttr("class").css({
			"position" : "absolute",
			"height" : "0px",
			"top" : y,
			"left" : +x
		});
		clone.appendTo(lattice);
		return clone;
	},

	/**
	 * Get the treasure type.
	 */
	getTreasure : function(e) {
		var latticeId = "#" + e.target.id;
		// the treasure object
		return $(latticeId + " > img.treasure");
	},

	getTreasureClone : function(e) {
		var treasure = AnimationUtil.getTreasure(e);
		var tid = treasure.attr("id");
		return $("#" + tid + GlobalConstants.CLONED_TREASURE_ID_SUFFIX);
	},

	getLattice : function(e) {
		var latticeId = "#" + e.target.id;
		// the lattice jQuery object
		return $(latticeId);
	},

	getTragger : function() {
		var id = "#" + GlobalConstants.ANIMATION_TRIGGER_ID;
		var trigger = $(id);
		return trigger;
	}
};

/**
 * Define a animation handler for centralize the animation handle.
 */
var AnimationHandler = {
	_playAnimation : function(e, animationArray) {
		var event = e;
		if (animationArray == null || animationArray.length == 0) {
			return;
		}
		var animationDefine = animationArray.pop();
		var animation = Animations[animationDefine.name];

		AnimationUtil.getTragger().delay(animationDefine.delay).animate({
			"height" : "0px"
		}, 0, function() {
			// setTimeout(function() {
			animation.play(event);
			// });
			AnimationHandler._playAnimation(event, animationArray);
		});
	},
	/**
	 * Fire the animation.
	 * 
	 * @param event
	 */
	fireAnimation : function(e) {
		Animations._init(e);
		var treasure = AnimationUtil.getTreasure(e);
		var arr = AnimationStack[treasure.attr("treasureType")].slice().reverse();
		AnimationHandler._playAnimation(e, arr);
	}
};

/**
 * Setting the animation for each type of treasure.
 */
var AnimationStack = {
	// animate define for diamond type treasure
	diamond : [ {
		name : "hideLattice",
		delay : 0
	}, {
		name : "flickering",
		delay : 0
	}, {
		name : "progressivePop",
		delay : 0
	}, {
		name : "progressiveMinify",
		delay : 1000
	} ],

	// animate define for bomb type treasure
	bomb : [ {
		name : "hideLattice",
		delay : 0
	}, {
		name : "flickering",
		delay : 0
	}, {
		name : "progressivePop",
		delay : 0
	}, {
		name : "shocking",
		delay : 500
	}, {
		name : "explode",
		delay : 500
	} ]

};

/**
 * All animations definition.
 */
var Animations = {
	_init : function(e) {
		var tc = AnimationUtil.getTreasureClone(e);
		if (tc == null || tc.length == 0) {
			AnimationUtil.cloneAnimationTreasure(e);
		}
	},
	hideLattice : {
		"play" : function(e) {
			var lattice = AnimationUtil.getLattice(e);
			// hide lattice
			lattice.css("background-color", "transparent");
			// unbind the click action .
			lattice.unbind("click");
		}
	},

	flickering : {
		"play" : function(e) {
			// the treasure object
			var treasure = AnimationUtil.getTreasure(e);
			treasure.css("height", "50px");
			var i = 0, opct = 100;
			var pl = function() {
				if (i >= 5) {
					clearInterval(itv);
				} else {
					treasure.animate({
						"opacity" : opct
					}, 70);
					opct = opct == 100 ? 0 : 100;
					i++;
					itv = setInterval(pl, 71);
				}
			};
			var itv = setInterval(pl, 0);
		}
	},
	/**
	 * Play the animation when user click the masked treasure.
	 * 
	 * @param e
	 */
	progressivePop : {
		"play" : function(e) {
			var pos = AnimationUtil.getAbsoluteCenterPosition(e);
			var tc = AnimationUtil.getTreasureClone(e);

			var fx = tc.offset().left, fy = tc.offset().top, tx = pos.x, ty = pos.y;
			var ox = "+=" + (tx - fx), oy = "+=" + (ty - fy);

			tc.css({
				"opacity" : 100,
				"position" : "absolute",
				"left" : fx + "px"
			}).animate({
				"height" : GlobalConstants.TREASURE_MAX_WIDTH + "px",
				"left" : ox,
				"top" : oy
			}, 150, "swing");
		}
	},

	/**
	 * progressive minify
	 * 
	 * @param e
	 */
	progressiveMinify : {
		"play" : function(e) {
			var target = AnimationUtil.getTreasureClone(e);
			// treasure animation
			target.css({
				"position" : "absolute"
			}).animate({
				"height" : "0px",
				"opacity" : 0,
				"left" : $(window).width() + "px",
				"top" : "0px"
			}, 350);
		}
	},

	/**
	 * Transparency
	 */
	transparency : {
		"play" : function(e) {
			var treasure = AnimationUtil.getTreasure(e);
			treasure.animate({
				"opacity" : 0
			}, 50);
		}
	},

	/**
	 * Shocking
	 * 
	 * @param e
	 */
	shocking : {
		"play" : function(e) {
			var treasure = AnimationUtil.getTreasureClone(e);
			var shockMaxOffset = 4;

			var shockPosition = [ 'top', 'left' ], count = 0;
			shockIntervalObject = setInterval(function() {
				var randomPosition = shockPosition[count % 2];
				var shockOffset = (count++) % shockMaxOffset < 2 ? 0 : shockMaxOffset;
				var treasureCenterPosition = AnimationUtil.getAbsoluteCenterPosition(e);
				if (randomPosition == 'top') {
					shockOffset += treasureCenterPosition.y;
				} else {
					shockOffset += treasureCenterPosition.x;
				}
				treasure.css(randomPosition, shockOffset);
				if (count > 35) {
					clearInterval(shockIntervalObject);
					count = 0;
				}
			}, 32);
		}
	},

	/**
	 * @param e
	 */
	explode : {
		"play" : function(e) {
			var pos = AnimationUtil.getAbsoluteCenterPosition(e);
			var treasure = AnimationUtil.getTreasureClone(e);

			treasure.animate({
				"opacity" : 0
			}, 200);

			var masker = AnimationUtil.createPageMasker(e);
			var bomb = $("<img/>");
			bomb.attr("src", "bomb4.jpg").css({
				"width" : "0px",
				"height" : "0px",
				"border" : "0",
				"z-index" : "101",
				"position" : "absolute",
				"top" : pos.y + "px",
				"left" : pos.x + "px"
			}).appendTo(masker);

			bomb.animate({
				"top" : "0px",
				"left" : "0px",
				"width" : $(window).width(),
				"height" : $(window).height()
			}, 80).animate({
				"top" : pos.y + "px",
				"left" : pos.x + "px",
				"width" : "0px",
				"height" : "0px",
				"opacity" : 0
			}, 120, function() {
				AnimationUtil.removeMasker();
			});

			// var bg = "#000", i = 5;
			// $("body").css({
			// "background-color" : "#fff"
			// }).animate({
			// "opacity" : "0"
			// }, 3000);
		}
	}
};